/*
 * Date：10/23/18 10:15 PM
 * Author: guomw
 *
 */

package org.elanfox.intellicommunity.biz.service.core.equipment.impl;

import org.elanfox.intellicommunity.biz.entity.equipment.TrackPO;
import org.elanfox.intellicommunity.biz.repository.equipment.TrackRepository;
import org.elanfox.intellicommunity.biz.service.core.equipment.TrackService;
import org.elanfox.intellicommunity.data.base.base.AbstractSearchableCrudService;
import org.elanfox.intellicommunity.data.base.base.SpecificationAndSort;
import org.elanfox.intellicommunity.data.base.dto.BaseSaveDTO;
import org.elanfox.intellicommunity.data.base.dto.BaseSearchDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * 定位器相关service
 *
 * @author loutianxi
 * @date 2019-12-05
 */
@Service
public class TrackServiceImpl extends AbstractSearchableCrudService<TrackPO, Integer> implements TrackService {

    @Autowired
    private TrackRepository repository;

    protected TrackServiceImpl(TrackRepository repository) {
        super(repository);
    }

    @Override
    protected SpecificationAndSort<TrackPO> specificationAndSort(BaseSearchDTO condition) {
        Specification<TrackPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public TrackPO save(BaseSaveDTO saveDTO) {
        return null;
    }

    @Override
    public List<Double[]> find(Long startPoint, Long endPoint) {
        List<Double[]> douList = new ArrayList<>();
        List<TrackPO> list = repository.findByStartPointAndEndPoint(startPoint, endPoint);
        Integer nextPoint = 0;
        if (!CollectionUtils.isEmpty(list)) {
            //寻找第一个点
            for (TrackPO a : list) {
                if (douList.size() == 0 && a.getLastPoint() == null) {
                    Double[] point = {Double.parseDouble(a.getPoint().getLongitude()), Double.parseDouble(a.getPoint().getLatitude())};
                    douList.add(point);
                    nextPoint = a.getNextPoint();
                }
            }
            //寻找下一个点
            while (douList.size() < list.size()) {
                for (TrackPO a : list) {
                    if (a.getPoint().getId() == nextPoint) {
                        Double[] point = {Double.parseDouble(a.getPoint().getLongitude()), Double.parseDouble(a.getPoint().getLatitude())};
                        douList.add(point);
                        nextPoint = a.getNextPoint();
                    }
                }
            }
            return douList;
        }
        //如果没有轨迹查询反向轨迹
        list = repository.findByStartPointAndEndPoint(endPoint, startPoint);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        //找寻上一个点
        Integer lastPoint = 0;
        //寻找最后一个点
        for (TrackPO a : list) {
            if (douList.size() == 0 && a.getNextPoint() == null) {
                Double[] point = {Double.parseDouble(a.getPoint().getLongitude()), Double.parseDouble(a.getPoint().getLatitude())};
                douList.add(point);
                lastPoint = a.getLastPoint();
            }
        }
        //寻找下一个点
        while (douList.size() < list.size()) {
            for (TrackPO a : list) {
                if (a.getPoint().getId() == lastPoint) {
                    Double[] point = {Double.parseDouble(a.getPoint().getLongitude()), Double.parseDouble(a.getPoint().getLatitude())};
                    douList.add(point);
                    lastPoint = a.getLastPoint();
                }
            }
        }
        return douList;
    }

    @Override
    public TrackPO find(Long startPoint, Long endPoint, Integer pointId) {
        return repository.findByStartPointAndEndPointAndPoint_Id(startPoint, endPoint, pointId);
    }

    @Override
    public TrackPO findByPointId(Integer pointId) {
        return repository.findByPoint_Id(pointId);
    }

    @Override
    public void deleteByPointId(Integer pointId) {
        repository.deleteByPoint_Id(pointId);
    }

}
